/**
 * @file ArmorClassifierBase.h
 * @brief
 * @author LiuZhihao (2488288779@qq.com)
 * @date 2023-12-10
 *
 * @copyright Copyright (C) 2023, HITCRT_VISION, all rights reserved.
 *
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Author  <th>Description
 * <tr><td>2023-12-10 <td>LiuZhihao  <td>
 * </table>
 */
#pragma once
#include <boost/bind.hpp>
#include <chrono>
#include <cmath>
#include <iostream>
#include <opencv2/core.hpp>
#include <openvino/openvino.hpp>

#include "../basic/Basic.h"

namespace hitcrt {

float sigmoid(float x);

class ArmorClassifierBase {  /// 基于OpenVINO的数字分类器，含检测
   public:
    // 枚举类型
    //  网络分类模式，CLS_CONF表示含有误识别置信度检测的模型，CLS表示普通的分类模型
    typedef enum ClassifierIfConf {
        CLS = 0,
        CLS_CONF,
    } ClassifierIfConf;

    typedef enum ClassifierChannelType {
        ThreeChannel = 0,
        OneChannel,
    } ClassifierChannelType;

    // 网络推理设备
    typedef enum ClassifierDevice {
        CPU = 0,
        GPU,
    } CFdevice;

    ArmorClassifierBase(ClassifierChannelType classifierChannelType,
                        ClassifierIfConf classifierIfConf);

    ~ArmorClassifierBase();

    // 初始化
    bool init(std::string xmlPath, float maxConf, int class_number,
              ClassifierDevice classifierDevice);
    virtual Pattern apply(const std::vector<cv::Point2f>& srcPoints, const cv::Mat& srcImg);
    // 处理图像获取结果
    int inference(const cv::Mat& inframe);

    ClassifierChannelType m_classifierChannelType;  // 二值化单通道输入还是三通道模式

   protected:
    Pattern getPattern(const int classID);
    void perspectiveTransImpl(const std::vector<cv::Point2f>& srcPoints, const cv::Mat& inputSample,
                              cv::Mat& outputSample);
    virtual void getNumPic(const std::vector<cv::Point2f>& srcPoints, cv::Mat& outputSample);
    void setSrcImg(const cv::Mat& inputSample) { m_srcImg = inputSample; }
    void cvtColorImpl(cv::Mat& sample);
    cv::Mat m_srcImg;  // 原图

   private:
    const std::string toString(const ClassifierDevice& val) {
        switch (val) {
            case ClassifierDevice::CPU:
                return "CPU";
            case ClassifierDevice::GPU:
                return "GPU";
        }
    };

    const std::string toString(const ClassifierIfConf& val) {
        switch (val) {
            case ClassifierIfConf::CLS:
                return "CLS";
            case ClassifierIfConf::CLS_CONF:
                return "CLS_CONF";
        }
    };
    // 存储初始化获得的可执行网络
    ov::Core m_core;
    ov::CompiledModel m_compiledModel;
    ov::InferRequest m_inferRequest;
    ov::Tensor m_inputNode;
    ov::Shape m_tensorShape;

    // 参数区
    std::string m_xmlPath;  // OpenVINO模型xml文件路径
    float m_maxConf;        // 分类置信度
    ClassifierIfConf m_classifierIfConf;  // 网络分类模式，用来支持无置信度分类和有置信度分类
    ClassifierDevice m_classifierDevice;  // 网络推理设备
    int m_classNumber;
};
}  // namespace hitcrt